package com.sec.kun.test;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author zhoukun
 * @Date 2021/2/17 18:24
 */
@SpringBootTest
public class SpringBootTest1 {

    /*
     * 测试Token的生成
     */
    @Test
    public void createToken() {
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("0918")//声明的标识
                .setSubject("zhoukun")//主体
                .setIssuedAt(new Date())//创建日期
                //签名，第一个参数是算法，第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "loveYou");
        //获取jwt的Token
        String token = jwtBuilder.compact();
        System.out.println(token);
        System.out.println("--------------------------------------");
        //分割
        String []strs = token.split("\\.");
        String header = Base64Codec.BASE64.decodeToString(strs[0]);
        String payload = Base64Codec.BASE64.decodeToString(strs[1]);
        //第三部分解析出来一定会乱码
        String sign = Base64Codec.BASE64.decodeToString(strs[2]);
        System.out.println("头部：" + header);
        System.out.println("负载：" + payload);
        System.out.println("签名：" + sign);
    }

    /*
     *  测试Token的解析
     */
    @Test
    public void parseToken() {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwOTE4Iiwic3ViIjoiemhvdWt1biIsImlhdCI6MTYxMzU1Nzk2Nn0.UEQ6EDkhZ1xJfKg004Msu4NIHOKdHXhW3eatonwQfPc";
        //解析token，获取负载中的声明对象
        Claims claims = Jwts.parser()
                .setSigningKey("loveYou")//这个就是秘钥
                .parseClaimsJws(token)
                .getBody();
        //获取信息
        String id = claims.getId();
        String sub = claims.getSubject();
        Date date = claims.getIssuedAt();
        System.out.println("ID：" + id);
        System.out.println("签发人：" + sub);
        System.out.println("签发时间：" + date);
    }

    /*
     * 测试Token的生成(token过期校验)
     */
    @Test
    public void createTokentime() {
        //获取系统当前时间
        long current = System.currentTimeMillis();
        long expire = current + 1000 * 60;
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("0918")//声明的标识
                .setSubject("zhoukun")//主体
                .setIssuedAt(new Date())//创建日期
                //签名，第一个参数是算法，第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "loveYou")
                .setExpiration(new Date(expire));//设置过期时间，1分钟后失效
        //获取jwt的Token
        String token = jwtBuilder.compact();
        System.out.println(token);
        System.out.println("--------------------------------------");
        //分割
        String []strs = token.split("\\.");
        String header = Base64Codec.BASE64.decodeToString(strs[0]);
        String payload = Base64Codec.BASE64.decodeToString(strs[1]);
        //第三部分解析出来一定会乱码
        String sign = Base64Codec.BASE64.decodeToString(strs[2]);
        System.out.println("头部：" + header);
        System.out.println("负载：" + payload);
        System.out.println("签名：" + sign);
    }

    /**
     * 自定义claims
     */
    @Test
    public void createToken2() {
        //获取系统当前时间
        long current = System.currentTimeMillis();
        long expire = current + 1000 * 60;
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("0918")//声明的标识
                .setSubject("zhoukun")//主体
                .setIssuedAt(new Date())//创建日期
                //签名，第一个参数是算法，第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "loveYou")
                .setExpiration(new Date(expire))//设置过期时间，1分钟后失效
                .claim("name", "zhoukun")//自定义claims
                .claim("age", 20)
                .claim("like", "lllll")
                .claim("wantto", "西安");
        //获取jwt的Token
        String token = jwtBuilder.compact();
        System.out.println(token);
        System.out.println("--------------------------------------");
        //分割
        String []strs = token.split("\\.");
        String header = Base64Codec.BASE64.decodeToString(strs[0]);
        String payload = Base64Codec.BASE64.decodeToString(strs[1]);
        //第三部分解析出来一定会乱码
        String sign = Base64Codec.BASE64.decodeToString(strs[2]);
        System.out.println("头部：" + header);
        System.out.println("负载：" + payload);
        System.out.println("签名：" + sign);
    }
    /**
     * 自定义claims另一种方法
     */
    @Test
    public void createToken3() {
        //获取系统当前时间
        long current = System.currentTimeMillis();
        long expire = current + 1000 * 60;
        Map<String,Object> map = new HashMap<>();
        map.put("name", "zoukun");
        map.put("age", 20);
        map.put("like", "lllll");
        map.put("city", "西安");
        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("0918")//声明的标识
                .setSubject("zhoukun")//主体
                .setIssuedAt(new Date())//创建日期
                //签名，第一个参数是算法，第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "loveYou")
                .setExpiration(new Date(expire))//设置过期时间，1分钟后失效
                .addClaims(map);
        //获取jwt的Token
        String token = jwtBuilder.compact();
        System.out.println(token);
        System.out.println("--------------------------------------");
        //分割
        String []strs = token.split("\\.");
        String header = Base64Codec.BASE64.decodeToString(strs[0]);
        String payload = Base64Codec.BASE64.decodeToString(strs[1]);
        //第三部分解析出来一定会乱码
        String sign = Base64Codec.BASE64.decodeToString(strs[2]);
        System.out.println("头部：" + header);
        System.out.println("负载：" + payload);
        System.out.println("签名：" + sign);
    }
}
